######################################################################
# Time-stamp: <05/08/09 16:21:44 ostolop>
#
# Package: EP::Common::DBI::Action
#
# DBI object mapping to the *action* table
######################################################################
package EP::Common::DBI::Action;

use strict;
use base qw ( EP::Common::DBI );
use XML::LibXML;

EP::Common::DBI::Action->table ( 'ep_action' );
EP::Common::DBI::Action->sequence ( 'ep_action_seq' );

EP::Common::DBI::Action->columns ( Primary   => qw ( id ) );
EP::Common::DBI::Action->columns ( Essential => qw ( parent_action component dst_dataset root_dataset ep_date ) );

EP::Common::DBI::Action->has_a ( dst_dataset   => 'EP::Common::DBI::Dataset' );
EP::Common::DBI::Action->has_a ( root_dataset  => 'EP::Common::DBI::Dataset' );
EP::Common::DBI::Action->has_a ( parent_action => 'EP::Common::DBI::Action'  );
EP::Common::DBI::Action->has_a ( component     => 'EP::Common::DBI::Component' );
#EP::Common::DBI::Action->has_a ( metadata      => 'EP::Common::DBI::Action::Metadata' );

EP::Common::DBI::Action->has_many ( metadata => 'EP::Common::DBI::Action_Metadata' );

# sub: metadata_xml_doc
#   Creates an XML representation of action metadata
# returns:
#   An <XML::LibXML::Document> object.
sub metadata_xml_doc {
  my $self = shift;
  my ($meta_id) = @_;

  my $doc = XML::LibXML->createDocument ();
  my $root = $doc->createElement( "action_metadata" );
  $root->setAttribute ( "component_id",    $self->component->id );
  $root->setAttribute ( "component_name",    $self->component->name );
  $root->setAttribute ( "dst_dataset_id",  $self->dst_dataset->id );
  $root->setAttribute ( "date",            $self->ep_date );
  $root->setAttribute ( "root_dataset_id", $self->root_dataset->id );
  $doc->setDocumentElement( $root );

  foreach ( $self->metadata ) {
    next if defined $meta_id and $_->id != $meta_id;
    my $meta = $doc->createElement("meta");
    $meta->setAttribute ( "id", $_->id );
    $meta->setAttribute ( "name",  $_->name );
    $meta->setAttribute ( "type",  $_->type || "" );
    $meta->setAttribute ( "uuid",  $_->uuid || "" );
    $meta->setAttribute ( "label", $_->label || "" );
    $meta->appendChild ( $doc->createTextNode ( $_->value ) ) if $_->value;
    $root->appendChild ( $meta );
  }

  return $doc;
}

sub blank_metadata_xml_doc {
  my ( $epc_action ) = shift;

  my $doc = XML::LibXML->createDocument ();
  my $root = $doc->createElement( "action_metadata" );
  $root->setAttribute ( "component_id", $epc_action->findvalue ( 'ancestor::component/@id' ) );
  $doc->setDocumentElement( $root );

  my $meta = $doc->createElement("meta");
  $meta->setAttribute ( "id", "0");
  $meta->setAttribute ( "name",  "" );
  $meta->setAttribute ( "type",  "blank" );
  $meta->setAttribute ( "uuid",  "" );
  $meta->setAttribute ( "label", "" );
  $meta->appendChild ( $doc->createTextNode ( "No metadata!" ) );
  $root->appendChild ( $meta );

  return $doc;
}

package EP::Common::DBI::Action::Metadata;

use Storable;
use MIME::Base64;

use strict;
use overload ( '""'  => \&stringify );

sub stringify {
  my $self = shift;

#  warn "Freezing ...";
  my $frozen = encode_base64 ( Storable::nfreeze ( $self ) );
  return $frozen;
}

sub new {
  my $proto = shift;
  my $class = ref ( $proto ) || $proto;

  my $metadata;
  if ( ref ( $_[0] )  eq "HASH" ) {
#    warn "New from hash...";
    $metadata = $_[0];
    delete $metadata->{visualization} if exists $metadata->{visualization};
  } else {
    my $frozen = shift;
#    warn "Thawing...";
    $metadata = Storable::thaw ( decode_base64 ( $frozen ) ) if $frozen;
  }

  my $self = $metadata;

  bless $self, $class;
  return $self;
}

1;
